<?php
/**
 * Created by PhpStorm.
 * User: mr.lee
 * Date: 2018/11/22
 * Time: 6:34 PM
 */

namespace app\api\controller;


use Alipay\Alipayobj;
use app\common\controller\ActionLogs;
use app\common\controller\Payinfo;
use app\common\controller\TemplateMsg;
use app\common\model\Agent;
use app\common\model\Merchant;
use app\common\model\Paylog;
use app\common\model\WxOpen;
use Bank\HuifuServer;
use Wechat\Wxobjopen;

class WxAppCreateOrder extends Pub
{
    public function create_order($param)
    {

        switch ($param['channel']) {
            case "0":
                $rarr = $this->create_official_order($param, "wechat_way");
                break;
            case "1":
                $rarr = $this->create_official_order($param, "ali_way");
                break;
            case "11":
                $rarr = $this->create_micro_order($param);
                break;
            default:
                $rarr = $this->create_other_order($param);
                break;
        }

        return $rarr;

    }

    private function create_other_order($param)
    {
        $out_trade_no = $this->getorderid($param['merchantid']);
        $data['mid'] = $param['merchantid'];
        $data['orderid'] = $out_trade_no;
        $data['source'] = $param['source'];
        $data['pay_fs'] = $param['channel'];
        $data['d_cashier'] = $param['device_id'];

        $data['kuantai'] = $param['kuantai'];
        $data['price'] = $param['total_fee'];
        $data['yf_price'] = $param['total_fee'];
        $data['pay_cate'] = $param['pay_cate'];
        $data['add_time'] = time();
        $Paylog = new Paylog();
        $add = $Paylog->save($data);
        $infos = ['out_trade_no' => $out_trade_no];
        if ($add) {
            $rarr['return_code'] = "SUCCESS";
            $rarr['return_msg'] = '';
            $rarr['result_code'] = 'SUCCESS';
            $rarr['result_msg'] = '';
            $rarr['info'] = $infos;
        } else {
            $rarr['return_code'] = "SUCCESS";
            $rarr['return_msg'] = '';
            $rarr['result_code'] = 'FAIL';
            $rarr['result_msg'] = '订单号获取失败,请尝试重新发起支付';
        }

        return $rarr;
    }

    private function create_official_order($param, $type)
    {
        $Merchant = new Merchant();
        $pay_way = $Merchant->where('id', $param['merchantid'])->value($type);
        $param['pay_way']=$pay_way;
        if ($param['channel'] == 0) {
            switch ($pay_way) {
                case '0':
                    $rarr = $this->create_wx_official_order($param);
                    break;
                case '1':
                    $rarr = $this->create_wx_official_order($param);
                    break;
                case '10':
                    $rarr = "";
                    break;
            }
        }
        return $rarr;


    }

    //生成微信官方扫码支付订单APP支付
    public function create_wx_official_order($param)
    {

        //生成订单
        $out_trade_no = $this->getorderid($param['merchantid']);;
        $sub_openid = $param['sub_openid'];
        $param['out_trade_no'] = $out_trade_no;
        $this->createpaylog($param);
        //获取配置
        $Merchant = new Merchant();
        $map['id'] = $param['merchantid'];
        $config = $Merchant->where($map)->find();
        $options = array(
            'appid' => $config['app_appid'], // 填写高级调用功能的app id
            'partnerid' => $config['app_mch_id'], // 财付通商户身份标识
            'partnerkey' => $config['app_mch_key'], // 财付通商户权限密钥Key
        );
        $appid = $config['app_appid'];
        $mch_id = $config['app_mch_id'];
        //获取微信支付
        $weObj = new Wxobjopen($options);
        $body = "快捷支付";
        $total_fee = $param['total_fee'] * 100;
        $openid = "";
        $notify_url = 'https://api.wunengkeji.com/notify.php/wxofficialappnotify';
        $spbill_create_ip = $_SERVER["REMOTE_ADDR"];
        $nonce_str = $weObj->generateNonceStr();
        $param_data['appid'] = $appid;
        $param_data['mch_id'] = $mch_id;
        $param_data['nonce_str'] = $nonce_str;
        $param_data['body'] = $body;
        $param_data['out_trade_no'] = $out_trade_no;
        $param_data['total_fee'] = $total_fee;
        $param_data['spbill_create_ip'] = $spbill_create_ip;
        $param_data['notify_url'] = $notify_url;
        $param_data['openid'] = $openid;
        $param_data['sub_openid'] = $sub_openid;
        $param_data['attach'] = $param['attach'];
        $param_data['trade_type'] = "APP";
        $pay_xml = $weObj->createWxPackageXml($param_data);
        $pay_xml = $weObj->get_pay_id($pay_xml);
        if ($pay_xml['return_code'] == "SUCCESS") {
            //支付签名参数
            $prepay_id = $pay_xml['prepay_id'];
            $timeStamp = time();
            $signApiObj["appid"] = $appid;
            $signApiObj["partnerid"] = $mch_id;
            $signApiObj["prepayid"] = $prepay_id;
            $signApiObj["noncestr"] = $nonce_str;
            $signApiObj["timestamp"] = $timeStamp;
            $signApiObj["package"] = "Sign=WXPay";        //
            //end
            $jsApiObj["appId"] = $appid;
            $jsApiObj["partnerId"] = $mch_id;
            $jsApiObj["prepayId"] = $prepay_id;
            $jsApiObj["nonceStr"] = $nonce_str;
            $jsApiObj["timeStamp"] = $timeStamp;
            $jsApiObj["package"] = "Sign=WXPay";        //
            $jsApiObj["paySign"] = $this->getPaySignature($signApiObj,$config['app_mch_key']);
//            $jsApiObj["signType"] = "MD5";
//            $jsApiObj["package"] = "prepay_id=" . $prepay_id;        //

            //END
            $rarr['return_code'] = "SUCCESS";
            $rarr['return_msg'] = '';
            $rarr['result_code'] = 'SUCCESS';
            $rarr['result_msg'] = '';
            $rarr['out_trade_no'] = $out_trade_no;
            $rarr['info'] = $jsApiObj;
        } else {
            $rarr['return_code'] = "SUCCESS";
            $rarr['return_msg'] = '';
            $rarr['result_code'] = 'FAIL';
            $rarr['result_msg'] = $pay_xml['return_msg'];
        }
        return $rarr;
    }


    //生成微信官方扫码支付订单微信小程序支付
    public function create_wx_official_order_wxapp($param)
    {

        //生成订单
        $out_trade_no = $this->getorderid($param['merchantid']);;
        $sub_openid = $param['sub_openid'];
        $param['out_trade_no'] = $out_trade_no;
        $this->createpaylog($param);
        //获取配置
        $WxOpen = new WxOpen();
        $Merchant = new Merchant();
        $Agent = new Agent();
        $map['id'] = $param['merchantid'];
        $config = $Merchant->where($map)->find();
        $userwx = $WxOpen->where(array('id' => $config['wx_open_id']))->find();
        $agent = $Agent->where(array('id' => $config['agent']))->find();
        $users = $WxOpen->where(array('id' => $agent['wx_open_id']))->find();
        $sub_appid = $userwx['authorizer_appid'];
//        $options = array(
//            'appid' => $config['wxapp_appid'], // 填写高级调用功能的app id
//            'partnerid' => $config['app_mch_id'], // 财付通商户身份标识
//            'partnerkey' => $config['app_mch_key'], // 财付通商户权限密钥Key
//        );
        $options = array(
            'appid' => $users['authorizer_appid'], // 填写高级调用功能的app id
            'partnerid' => $agent['partnerid'], // 财付通商户身份标识
            'partnerkey' => $agent['partnerkey'], // 财付通商户权限密钥Key
        );

        $appid = $users['authorizer_appid'];
        $sub_appid = $config['wxapp_appid'];
        $mch_id = $agent['partnerid'];
        $sub_mch_id = $config['app_mch_id'];
        //获取微信支付
        $weObj = new Wxobjopen($options);
        $body = "快捷支付";
        $total_fee = $param['total_fee'] * 100;
        $openid = "";
        $notify_url = 'https://api.wunengkeji.com/notify.php/wxofficialappnotify';
        $spbill_create_ip = $_SERVER["REMOTE_ADDR"];
        $nonce_str = $weObj->generateNonceStr();

        $param_data['appid'] = $appid;
        $param_data['sub_appid'] = $sub_appid;
        $param_data['mch_id'] = $mch_id;
        $param_data['sub_mch_id'] = $sub_mch_id;
        $param_data['nonce_str'] = $nonce_str;
        $param_data['body'] = $body;
        $param_data['out_trade_no'] = $out_trade_no;
        $param_data['total_fee'] = $total_fee;
        $param_data['spbill_create_ip'] = $spbill_create_ip;
        $param_data['notify_url'] = $notify_url;
        $param_data['openid'] = $openid;
        $param_data['sub_openid'] = $sub_openid;
        $param_data['attach'] = $param['attach'];
        $param_data['trade_type'] = "JSAPI";
        $param_data["sign_type"] = "MD5";
//        trace( "create_wx_official_order_wxapp-1：" . json_encode($param_data,256),'SysRunErrorLog');
        $pay_xml = $weObj->createWxPackageXml($param_data);
        $pay_xml = $weObj->get_pay_id($pay_xml);
        if ($pay_xml['return_code'] == "SUCCESS" && $pay_xml['result_code'] == "SUCCESS") {
            //支付签名参数 
            $prepay_id = $pay_xml['prepay_id'];
            $timeStamp = time();
            $signApiObj["appid"] = $appid;
            $signApiObj["partnerid"] = $mch_id;
            $signApiObj["prepayid"] = $prepay_id;
            $signApiObj["noncestr"] = $nonce_str;
            $signApiObj["timestamp"] =  "$timeStamp";
            $signApiObj["package"] = "Sign=WXPay";        //
            //end
            $jsApiObj["appId"] = $sub_appid;
//            $jsApiObj["partnerId"] = $mch_id;
            $jsApiObj["nonceStr"] = $nonce_str;
            $jsApiObj["timeStamp"] = "$timeStamp";
            $jsApiObj["package"] = "prepay_id=" . $prepay_id;
            $jsApiObj["signType"] = "MD5";
            $jsApiObj["paySign"] = $weObj->getPaySignature($jsApiObj);
//            $jsApiObj["signType"] = "MD5";
//            $jsApiObj["package"] = "prepay_id=" . $prepay_id;        //

            //END
            $rarr['return_code'] = "SUCCESS";
            $rarr['return_msg'] = '';
            $rarr['result_code'] = 'SUCCESS';
            $rarr['result_msg'] = '';
            $rarr['out_trade_no'] = $out_trade_no;
            $rarr['info'] = $jsApiObj;
        } else {
            $rarr['return_code'] = "SUCCESS";
            $rarr['return_msg'] = '';
            $rarr['result_code'] = 'FAIL';
            $rarr['result_msg'] = $pay_xml;
        }
        return $rarr;
    }

    //生成微信官方扫码支付订单微信小程序支付
    public function create_wx_official_order_wxapp_bak($param)
    {

        //生成订单
        $out_trade_no = $this->getorderid($param['merchantid']);;
        $sub_openid = $param['sub_openid'];
        $param['out_trade_no'] = $out_trade_no;
        $this->createpaylog($param);
        //获取配置
        $Merchant = new Merchant();
        $map['id'] = $param['merchantid'];
        $config = $Merchant->where($map)->find();
        $options = array(
            'appid' => $config['wxapp_appid'], // 填写高级调用功能的app id
            'partnerid' => $config['app_mch_id'], // 财付通商户身份标识
            'partnerkey' => $config['app_mch_key'], // 财付通商户权限密钥Key
        );
        $appid = $config['wxapp_appid'];
        $mch_id = $config['app_mch_id'];
        //获取微信支付
        $weObj = new Wxobjopen($options);
        $body = "快捷支付";
        $total_fee = $param['total_fee'] * 100;
        $openid = $param['sub_openid'];
        $notify_url = 'https://api.wunengkeji.com/notify.php/wxofficialappnotify';
        $spbill_create_ip = $_SERVER["REMOTE_ADDR"];
        $nonce_str = $weObj->generateNonceStr();
        $param_data['appid'] = $appid;
        $param_data['mch_id'] = $mch_id;
        $param_data['nonce_str'] = $nonce_str;
        $param_data['body'] = $body;
        $param_data['out_trade_no'] = $out_trade_no;
        $param_data['total_fee'] = $total_fee;
        $param_data['spbill_create_ip'] = $spbill_create_ip;
        $param_data['notify_url'] = $notify_url;
        $param_data['openid'] = $openid;
        $param_data['sub_openid'] = $sub_openid;
        $param_data['attach'] = $param['attach'];
        $param_data['trade_type'] = "JSAPI";
//        $param_data["sign_type"] = "MD5";
        $pay_xml = $weObj->createWxPackageXml($param_data);
        $pay_xml = $weObj->get_pay_id($pay_xml);
        if ($pay_xml['return_code'] == "SUCCESS" && $pay_xml['result_code'] == "SUCCESS") {
            //支付签名参数
            $prepay_id = $pay_xml['prepay_id'];
            $timeStamp = time();
            $signApiObj["appid"] = $appid;
            $signApiObj["partnerid"] = $mch_id;
            $signApiObj["prepayid"] = $prepay_id;
            $signApiObj["noncestr"] = $nonce_str;
            $signApiObj["timestamp"] =  "$timeStamp";
            $signApiObj["package"] = "Sign=WXPay";        //
            //end
            $jsApiObj["appId"] = $appid;
//            $jsApiObj["partnerId"] = $mch_id;
            $jsApiObj["nonceStr"] = $nonce_str;
            $jsApiObj["timeStamp"] = "$timeStamp";
            $jsApiObj["package"] = "prepay_id=" . $prepay_id;
            $jsApiObj["signType"] = "MD5";
            $jsApiObj["paySign"] = $this->getPaySignature($jsApiObj,$config['app_mch_key']);
//            $jsApiObj["signType"] = "MD5";
//            $jsApiObj["package"] = "prepay_id=" . $prepay_id;        //

            //END
            $rarr['return_code'] = "SUCCESS";
            $rarr['return_msg'] = '';
            $rarr['result_code'] = 'SUCCESS';
            $rarr['result_msg'] = '';
            $rarr['out_trade_no'] = $out_trade_no;
            $rarr['info'] = $jsApiObj;
        } else {
            $rarr['return_code'] = "SUCCESS";
            $rarr['return_msg'] = '';
            $rarr['result_code'] = 'FAIL';
            $rarr['result_msg'] = $pay_xml;
        }
        return $rarr;
    }


    public function getPaySignature($arrdata,$partnerkey)
    {
        ksort($arrdata);
        $paramstring = "";
        foreach ($arrdata as $key => $value) {
            if (strlen($paramstring) == 0)
                $paramstring .= $key . "=" . $value;
            else
                $paramstring .= "&" . $key . "=" . $value;
        }
        $paramstring = $paramstring . "&key=" . $partnerkey;
        $paySign = MD5($paramstring);
        $sign = strtoupper($paySign);
        return $sign;
    }


    public function wxorderquery($param)
    {
        try {
            $param['source_type'] = !empty($param['source_type'])?$param['source_type']:'app';
            //获取配置
            $WxOpen = new WxOpen();
            $Merchant = new Merchant();
            $Agent = new Agent();
            $map['id'] = $param['merchantid'];
            $config = $Merchant->where($map)->find();
            $agent = $Agent->where(array('id' => $config['agent']))->find();
            $agentwxopen = $WxOpen->where(array('id' => $agent['wx_open_id']))->find();
            //END
            $Merchant = new Merchant();
            $sh = $param['merchantid'];
            $map['id'] = $param['merchantid'];
            $config = $Merchant->where($map)->find();
            //END
            if ($param['source_type'] == "app") {
                //app查询
                $sub_mch_id = $config['app_mch_id'];
                $sub_appid = $config['app_appid'];
            }elseif($param['source_type'] == "wxapp") {
                //wxapp查询
                $sub_mch_id = $config['app_mch_id'];
                $sub_appid = $config['wxapp_appid'];
            }else{
                $rarr['return_code'] = "FAIL";
                $rarr['return_msg'] = '来源错误';
                $rarr['result_code'] = 'FAIL';
                $rarr['result_msg'] = '来源错误';
                return $rarr;
            }
            //END
            $options = array(
                'appid' => $agentwxopen['authorizer_appid'], // 填写高级调用功能的app id
                'partnerid' => $agent['partnerid'], // 财付通商户身份标识
                'partnerkey' => $agent['partnerkey'], // 财付通商户权限密钥Key
            );
            $weObj = new Wxobjopen($options);
            $appid = $agentwxopen['authorizer_appid'];
            $mch_id = $agent['partnerid'];
            $out_trade_no = $param['out_trade_no'];
            $nonce_str = $weObj->generateNonceStr();
            $arrdata = array(
                "appid" => $appid,
                "mch_id" => $mch_id,
                "sub_appid" => $sub_appid,
                "sub_mch_id" => $sub_mch_id,
                "nonce_str" => $nonce_str,
                "out_trade_no" => $out_trade_no
            );
            $pay_xml = $weObj->createWxPackageXml($arrdata);
            $pay_xml = $weObj->getPayNum($pay_xml);
            $rarr = $this->wxpay_statu($pay_xml,$sh,$out_trade_no);
        } catch (\Exception $e) {
            $rarr['return_code'] = "FAIL";
            $rarr['return_msg'] = '系统错误';
            $rarr['result_code'] = 'FAIL';
            $rarr['result_msg'] = '系统错误' . $e->getMessage();;
        }
        return $rarr;

    }

    public function wxpay_statu($pay_xml, $id, $orderid)
    {
        try {
            $Paylog = new Paylog();
            $payinfoa = $Paylog->where(['orderid' => $orderid])->find();
            if ($payinfoa['pay_fs'] == 0 || $payinfoa['pay_fs'] == 2) {
                if ($pay_xml['return_code'] == "SUCCESS" && $pay_xml['trade_state'] == "SUCCESS") {
                    //END
                    $data['pay_statu'] = 1;
                    $data['orderno'] = $pay_xml['transaction_id'];
                    $data['ser_openid'] = $pay_xml['openid'];
                    $data['pay_time'] = date('Y-m-d H:i:s', strtotime($pay_xml['time_end']));
                    $data['payinfo'] = json_encode($pay_xml, true);
                    $data['price'] = $pay_xml['total_fee'] / 100;
                    if(isset($pay_xml['sub_openid'])){
                        $data['sub_openid'] = $pay_xml['sub_openid'];
                    }
                    $data['tzzt'] = 1;
                    //费率
                    $PayInfo = new Payinfo();
                    $data['service_charge'] = $PayInfo->service_charge($payinfoa['mid'], $payinfoa['price'], $payinfoa['pay_fs']);
                    $Paylog->where(['orderid' => $orderid])->update($data);
                    //END
                    $TemplateMsg = new TemplateMsg();
                    $TemplateMsg->send_tpl('pay', array('merchantid' => $id, 'orderid' => $orderid));
                    //END
                    $Notify=new CreateNotify();
                    $param['out_trade_no']=$orderid;
                    $param['merchantid']=$id;
                    $Notify->pay_notify($param);
                    $arrc['return_code'] = "SUCCESS";
                    $arrc['result_code'] = "SUCCESS";
                    $arrc['return_msg'] = "支付成功";
                    $arrc['result_msg'] = "支付成功";
                    //END
                    $arrc['out_trade_no'] = $payinfoa['orderid'];
                    $arrc['total_fee'] = $payinfoa['price'];
                    $arrc['order_no'] = $payinfoa['orderno'];
                    $arrc['end_time'] = $payinfoa['pay_time'];
                    $arrc['payinfo'] = $payinfoa['payinfo'];
                }else{
                    $arrc['return_code'] = "SUCCESS";
                    $arrc['result_code'] = "FAIL";
                    if (isset($pay_xml['trade_state'])) {
                        $arrc['return_msg'] = translate($pay_xml['trade_state']);
                        $arrc['result_msg'] = translate($pay_xml['trade_state']);
                    }elseif (isset($pay_xml['err_code']) && isset($pay_xml['err_code_des'])){
                        $arrc['return_msg'] = translate($pay_xml['err_code']);
                        $arrc['result_msg'] = translate($pay_xml['err_code_des']);
                    }else{
                        $arrc['return_msg'] = "SUCCESS";
                        $arrc['result_msg'] = "支付失败";
                        $arrc['result_msg_xml'] = json_encode($pay_xml,JSON_UNESCAPED_UNICODE);
                    }
                }
            }else{
                $arrc['return_code'] = "SUCCESS";
                $arrc['result_code'] = "FAIL";
                $arrc['return_msg'] = "支付成功";
                $arrc['result_msg'] = "错误的支付方式";
            }
        } catch (\Exception $e) {
            $arrc['return_code'] = "FAIL";
            $arrc['return_msg'] = '系统错误';
            $arrc['result_code'] = 'FAIL';
            $arrc['result_msg'] = '系统错误' . $e->getMessage();
        }
        $ActionLogs = new ActionLogs();
        $ActionLogs->writelog("osapi", "clientlog", "wxpay_statu", "res:", $arrc);
        return $arrc;
    }


    private function createpaylog($param)
    {
        $data['orderid'] = $param['out_trade_no'];
        $data['mid'] = $param['merchantid'];
        $data['openid'] = $param['sub_openid'];
        $data['pay_fs'] = $param['channel'];
        $data['pay_statu'] = 0;
        $data['pay_way'] = $param['pay_way'];
        $data['price'] = $param['total_fee'];
        $data['yf_price'] = $param['total_fee'];
        $data['zk_price'] = 0;
        $data['pay_cate'] = $param['pay_cate'];
        $data['d_cashier'] = $param['device_id'];
        $data['kuantai'] = $param['kuantai'];
        $data['source'] = $param['source'];
        $data['source_type'] = isset($param['source_type'])?$param['source_type']:"web";
        $data['add_time'] = time();
        $data['attach'] = $param['attach'];
        if (isset($param['trade_no'])) {
            $data['trade_no'] = $param['trade_no'];;
        }
        $Paylog = new Paylog();
        $Paylog->save($data);


    }

    public function gethuifuorder($sh)
    {
        $order = "H" . $sh . "f" . date('YmdHis') . rand(10000, 99999);
        return $order;

    }
}